//
//  FDWebSocketTool.m
//  FD
//
//  Created by xiaofang wang on 2019/1/4.
//  Copyright © 2019年 ZhiYuan Network. All rights reserved.
//
// 1.什么是socket？
// 2.一共需要几个socket. push


//下载骑手坐标: /websocket/position/subscribe?userOrderId={{userOrderId}}
//获取消息推送：/websocket/push
//一个接口就是一个socket？

#import "FDPushWebSocketTool.h"
#import <SRWebSocket.h> //websocket
#import "RBDataBaseManager.h" //本地数据库
//PushMsgModel.h

@interface FDPushWebSocketTool()<SRWebSocketDelegate>
/**推送socket*/
@property (nonatomic, strong) SRWebSocket *pushwebSocket;
@end

@implementation FDPushWebSocketTool

/**单例类:推送socket单例类*/
+ (instancetype)defaultFdWebPushSockcet {

    static FDPushWebSocketTool *defatultPushSocket = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defatultPushSocket = [[FDPushWebSocketTool alloc] init];
    });
    
    return defatultPushSocket;
}

#pragma mark - 一 接口
- (void)setupAndOpenPushWebSocket {
    
    //1-19
    self.isFDPushWebSocketConnect = NO;//没连接
    
    //1.先清空之前的
    self.pushwebSocket.delegate = nil;
    [self.pushwebSocket close];

    
    //2.创建网络请求
    NSURLRequest *req = [FDHttpAPi rb_URLRequestWithUrlAPI:@"/websocket/push"];
    //3.根据 request 创建一个socket
    self.pushwebSocket = [[SRWebSocket alloc] initWithURLRequest:req];
    
    self.pushwebSocket.delegate = self;
    
    [self.pushwebSocket open]; //打开
    
//    [self saveMessageToLocalDB]; //测试保存本地
}

//断开连接
- (void)closePushWebSocket {
    [self.pushwebSocket close];
}

- (void)sendDataWithMessageId:(NSString *)messageId {
    
    if ([NSString isEmptyString:messageId]) {
        FDLog(@"messageId:为空,操作无效");
        return;
    }
    
    NSDictionary *sendDic = @{@"event":@"PUSH_READ",
                              @"data":@{@"id":messageId}
                              };
    
    //将dic 转换为json
    //tips:传JSON不能传NSData 会提示:xxBad Binary xxxx
    NSString *jsonStr = [self jsonFromDic:sendDic];

    // Send a UTF8 String or Data.
    [self.pushwebSocket send:jsonStr];
}


//!!!!:本地数据
- (void)saveMessageToLocalDB {
    [self readLocalJSON];
}

- (void)readLocalJSON {
    //读取本地json
    NSString *path = [[NSBundle mainBundle] pathForResource:@"push" ofType:@"json"];
    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
    NSError *err = nil;
    
    
    NSArray *arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&err];
    
    for (NSDictionary *dic in arr) {
        PushMsgModel *model = [PushMsgModel mj_objectWithKeyValues:dic[@"data"]];
//        FDLog(@"%@",model);
        //转model
        [[RBDataBaseManager shareDataBaseQueueManager] addMessageModel:model];
    }
}

#pragma mark - 二 privateMethod
- (NSString *)jsonFromDic:(NSDictionary *)dic {
    if (dic == nil) {
        FDLog(@"字典为空操作无效");
        return @"";
    }
    
    NSError *err = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&err];
    
    if (err) {
        FDLog(@"dic 转 JSON 失败:%@",err);
        return @"";
    }
    
    //utf8编码的字符串
    NSString *jsonstr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    return jsonstr;
}

//json--->dic
- (NSDictionary *)dicFromJSON:(NSString *)jsonstring {

    if ([NSString isEmptyString:jsonstring]) {
        return nil;
    }
    
    
    NSData *jsondata = [jsonstring dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err = nil;
    
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsondata options:NSJSONReadingMutableLeaves error:&err];
    
    if (err) {
        FDLog(@"错误:%@",err);
        return nil;
    }
    
    return dic;
}



#pragma mark - 三 SRWebSocketDelegate
//0.已经连接上了
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
    FDLog(@"push webSocket connected");

    self.isFDPushWebSocketConnect = YES;//2019-1-19
}

//1.连接失败以及原因的回调
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
    FDLog(@"webSocket failed with Errow %@",error);
    
    self.pushwebSocket  = nil; //清空
    self.isFDPushWebSocketConnect = NO;//2019-1-19
}

//2.接收到消息的回调
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
    FDLog(@"Received \"%@\"",message);
    
    //1.把id传给你
    //2.把消息存本地数据库
    //3.使用AWS加载模板,加载resource 跳转网页展示。
    //4.发通知显示小圆点:首页 和 我的页面
    NSDictionary *respondic = [self dicFromJSON:message];
    
    NSString *event = respondic[@"event"];
    if ([event isEqualToString:@"PUSH"]) { //消息推送
        NSDictionary *dic = respondic[@"data"];
        
        //转化下 easydic
        NSDictionary *easyDic = [self reAssembleMessageDic:dic];
        
        //转model
        PushMsgModel *model = [PushMsgModel mj_objectWithKeyValues:easyDic];
        
        FDLog(@"推送消息模型:%@",model);
        
        //以 msgId为id同样的消息只能存储一次。
        //保存到本地。
        [[RBDataBaseManager shareDataBaseQueueManager] addMessageModel:model];
        
        //id传给服务器。不然服务器会一直发送。
        [self sendDataWithMessageId:dic[@"id"]];
    }else {
        FDLog(@"不是推送消息:%@",respondic[@"describe"]);
    }
 
    //发通知显示小圆点
    [[NSNotificationCenter defaultCenter] postNotificationName:kPUSHMSGNotification object:self userInfo:@{@"msg":@"这是websocket推送消息通知 kPUSHMSGNotification"}];
}

//重新组装信息字典
- (NSDictionary *)reAssembleMessageDic:(NSDictionary *)dic {
    
    NSMutableDictionary *easyDicM = [NSMutableDictionary dictionary];
    NSString *messageId = dic[@"id"];
    NSString *type = dic[@"type"];
    NSString *title = dic[@"body"][@"title"];
    NSString *thumbnail = dic[@"body"][@"thumbnail"];
    NSString *resource = dic[@"body"][@"resource"];
    NSNumber *createTime = dic[@"createTime"]; //NSNumber类型不是NSString
    
    //新easydic
    [easyDicM setValue:messageId forKey:@"messageId"];
    [easyDicM setValue:type forKey:@"type"];
    [easyDicM setValue:title forKey:@"title"];
    [easyDicM setValue:thumbnail forKey:@"thumbnail"];
    [easyDicM setValue:resource forKey:@"resource"];
    [easyDicM setValue:createTime forKey:@"createTime"];
    
    return [easyDicM copy];
}



//3.socket关闭
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {
    
    self.isFDPushWebSocketConnect = NO;//2019-1-19
    FDLog(@"push websocket closed code:%ld reason:%@ wasClean:%@",code,reason,(wasClean ? @"YES" : @"NO"));
    self.pushwebSocket = nil; //清空
}

@end
